﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using YamlDotNet.Core.Tokens;

namespace PerpheralDevice;
/// <summary>
///  外设上的物理单元
/// </summary>
public abstract class PerpDevUnit {
    protected int TestIndex { get; set; }
    protected static int mfTestIndex = 0;


    public PerpDev PerpDev { get; protected set; }
    public abstract string UnitID { get; }

    private readonly List<object> OnStatusChangedActionList = [];
    /// <summary>
    /// 外设物理单元的状态发生变化
    /// </summary>
    /// <returns></returns>
    protected PerpDevUnit OnStatusChangedRaise() {
        Queue<object> tempQueue = new(this.OnStatusChangedActionList);
        while (tempQueue.Count > 0) { 
            object tempAction = tempQueue.Dequeue();
            Task.Factory.StartNew((action) => {
                MethodInfo? tempMethodInfo = action?.GetType().GetMethod("Invoke");
                tempMethodInfo?.Invoke(action, [this]);
            }, tempAction);
        }
        return this;
    }

    /// <summary>
    /// 注册事件委托 外设物理单元的状态发生变化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="action"></param>
    [MethodImpl(MethodImplOptions.Synchronized)]
    public T Add<T>(Action<T> action) where T : PerpDevUnit {
        if (!this.OnStatusChangedActionList.Contains(action)) {
            this.OnStatusChangedActionList.Add(action);
        }

        return this as T;
    }

    /// <summary>
    /// 取消事件委托 外设物理单元的状态发生变化
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="action"></param>
    [MethodImpl(MethodImplOptions.Synchronized)]
    public T Rem<T>(Action<T> action) where T : PerpDevUnit {
        if (this.OnStatusChangedActionList.Contains(action)) {
            this.OnStatusChangedActionList.Remove(action);
        }

        return this as T;
    }

}
